package com.sanqi;

import com.motu.vertx.module.utility.toolset.TimeUtils;
import com.motu.vertx.module.utility.toolset.Tool;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.Promise;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.json.JsonArray;
import io.vertx.ext.web.client.HttpRequest;
import io.vertx.ext.web.client.WebClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class SanqiSensitivewordEngine {
    private static final Logger logger = LoggerFactory.getLogger(SanqiSensitivewordEngine.class);

    public static final String PNYZJ_GAME_KEY = "pnyzj";
    public static final String PNYZJ_GAME_KEY_SEC = "XhL4EYhg4uXUh5pjkC6GyB4oZJY86tQG";
    public static final String PNYZJ_GAME_KEY_SECRET = "GrlNCTJ5A1BoexF";
    public static final String PNYZJ_CHECK_CHAT_URL = "http://api.gamechat.37.com/checkChatV2.php";

    public static final String PNYZJ_CHECK_USERNAME_URL = "http://api.gamechat.37.com/checkName.php";//check post 二选一
    public static final String PNYZJ_CHECK_FAMILY_NAME_URL = "http://api.gamechat.37.com/checkUnion.php";//check post 二选一
    public static final String PNYZJ_POST_USERNAME_URL = "http://api.gamechat.37.com/postName.php"; //检查用户名是否合规
    public static final String PNYZJ_POST_FAMILY_NAME_URL = "http://api.gamechat.37.com/postUnion.php";//检查联盟是否合规

    public static final String PNYZJ_GET_WORD_URL = "http://api.gamechat.37.com/getWord.php";//获取敏感字库

    public static final String SUCCESS = "1";

    public static final String CHANNEL_PUBLIC = "1";// 世界
    public static final String CHANNEL_BUDDY = "2";// 好友私聊
    public static final String CHANNEL_TEAM = "3";// 队伍
    public static final String CHANNEL_FAMILY = "4";// 工会

    public static final int FAMILY_NAME_TYPE = 1;// 工会名称
    public static final int FAMILY_NOTICE_TYPE = 2;// 工会公告

    /**
     * 检查聊天内容
     *
     * @return 通过true 失败 false
     */
    public static void checkChatWord(WebClient webClient, int serverid, String accountid, String userName,
                                                String toAccountid, String toUserName, String content, String channel,
                                                String ip, int time, long familyId, Handler<AsyncResult<Boolean>> onComplete) {
        try {
//            params.put("op", URLEncoder.encode(toCheck, "UTF-8"));//移动发行游戏的渠道参数
//            params.put("guildid", URLEncoder.encode(toCheck, "UTF-8"));//公会ID

            String url = PNYZJ_CHECK_CHAT_URL + "?game_key="+URLEncoder.encode(PNYZJ_GAME_KEY, "UTF-8")+"&sid="+URLEncoder.encode(String.valueOf(serverid), "UTF-8")+
                    "&username="+URLEncoder.encode(accountid, "UTF-8")+"&actor="+URLEncoder.encode(userName, "UTF-8")+
                    "&to_username="+URLEncoder.encode(toAccountid, "UTF-8")+"&to_actor="+URLEncoder.encode(toUserName, "UTF-8")+
                    "&content="+URLEncoder.encode(content, "UTF-8")+"&channel="+URLEncoder.encode(channel, "UTF-8")+
                    "&ip="+URLEncoder.encode(ip, "UTF-8")+"&time="+URLEncoder.encode(String.valueOf(time), "UTF-8")+
                    "&sign="+URLEncoder.encode(getSanqiChatSign(PNYZJ_GAME_KEY, serverid, accountid, toAccountid, channel, ip, time), "UTF-8")+
                    "&guildid="+URLEncoder.encode(String.valueOf(familyId), "UTF-8");
//            System.out.println(url);


//            HttpRequest<Buffer> request = webClient.getAbs(PNYZJ_URL).timeout(3000)
//                    .addQueryParam("game_key", URLEncoder.encode(PNYZJ_GAME_KEY, "UTF-8"))
//                    .addQueryParam("sid", URLEncoder.encode(String.valueOf(serverid), "UTF-8"))//游戏区服ID
//                    .addQueryParam("username", URLEncoder.encode(accountid, "UTF-8"))//玩家账号accountid
//                    .addQueryParam("actor", URLEncoder.encode(name, "UTF-8"))//角色名称
//                    .addQueryParam("to_username", URLEncoder.encode(toAccountid, "UTF-8"))//发送对象账号
//                    .addQueryParam("to_actor", URLEncoder.encode(toName, "UTF-8"))//发送对象角色名称
//                    .addQueryParam("content", URLEncoder.encode(content, "UTF-8"))//聊天内容
//                    .addQueryParam("channel", URLEncoder.encode(channel, "UTF-8"))//聊天类型1世界2私聊3队伍4工会
//                    .addQueryParam("ip", URLEncoder.encode(ip, "UTF-8"))//玩家ip
//                    .addQueryParam("time", URLEncoder.encode(String.valueOf(time), "UTF-8"))//当前Unix时间戳
//                    .addQueryParam("sign", URLEncoder.encode(getSanqiSign(PNYZJ_GAME_KEY, serverid, accountid, toAccountid, channel, ip, time), "UTF-8"));//接口签名参数

            HttpRequest<Buffer> request2 = webClient.getAbs(url).timeout(1000);
            request2.send(res-> {
                if (res.succeeded()) {
                    String result = res.result().bodyAsString();
                    if (SUCCESS.equals(result)) {
                        onComplete.handle(Future.succeededFuture(true));
                    } else {
                        logger.error("SanqiSensitivewordEngine checkChatWord result = {} url = {} ", result, url);
                        onComplete.handle(Future.succeededFuture(false));
                    }
                } else {
                    // 超时了 也直接返回成功
                    if (res.cause().getMessage().contains("timeout")) {
                        onComplete.handle(Future.succeededFuture(true));
                    } else {
                        logger.error("SanqiSensitivewordEngine checkChatWord timeout url = {} cause = {}", url, res.cause().getMessage());
                        onComplete.handle(Future.succeededFuture(false));
                    }
                }
            });
        } catch (Exception e) {
            logger.error("SanqiSensitivewordEngine checkChatWord encode error");
            onComplete.handle(Future.succeededFuture(false));
        }
    }

    /**
     * 上报玩家的取名
     * @param webClient
     * @param serverid 服务器ID
     * @param accountid 账号ID
     * @param userName 用户名称
     * @param userId 用户ID
     * @param ip
     * @param time
     * @return
     */
    public static void postUserName(WebClient webClient, int serverid, String accountid, String userName,
                                                long userId, String ip, int time, Handler<AsyncResult<Boolean>> onComplete) {

        try {
            // 计算签名
            Map<String, String> param = new  HashMap<>();
            param.put("game_key", PNYZJ_GAME_KEY);
            param.put("sid", String.valueOf(serverid));
            param.put("username", accountid);
            param.put("actor_id", String.valueOf(userId));
            param.put("ip", ip);
            param.put("time", String.valueOf(time));
            String sanqCommonSign = getSanqiCommonSign(param);

            // 构造请求对象
            HttpRequest<Buffer> request = webClient.postAbs(PNYZJ_POST_USERNAME_URL).timeout(3000)
                    .addQueryParam("game_key", URLEncoder.encode(PNYZJ_GAME_KEY, "UTF-8"))
                    .addQueryParam("sid", URLEncoder.encode(String.valueOf(serverid), "UTF-8"))//游戏区服ID
                    .addQueryParam("username", URLEncoder.encode(accountid, "UTF-8"))//玩家账号accountid
                    .addQueryParam("actor", URLEncoder.encode(userName, "UTF-8"))//角色名称
                    .addQueryParam("actor_id", URLEncoder.encode(String.valueOf(userId), "UTF-8"))//角色ID
                    .addQueryParam("ip", URLEncoder.encode(ip, "UTF-8"))//玩家ip
                    .addQueryParam("time", URLEncoder.encode(String.valueOf(time), "UTF-8"))//当前Unix时间戳
                    .addQueryParam("sign", URLEncoder.encode(sanqCommonSign, "UTF-8"));//接口签名参数

            request.send(res-> {
                if (res.succeeded()) {
                    String result = res.result().bodyAsString();
                    if (SUCCESS.equals(result)) {
                        onComplete.handle(Future.succeededFuture(true));
                    } else {
                        logger.error("SanqiSensitivewordEngine postUserName result = {} userName = {} accountid = {} userId = {}", result, userName, accountid, userId);
                        onComplete.handle(Future.succeededFuture(false));
                    }
                } else {
                    logger.error("SanqiSensitivewordEngine postUserName error userName = {} accountid = {} userId = {} cause = {}", userName, accountid, userId, res.cause().getMessage());
                    onComplete.handle(Future.succeededFuture(false));
                }
            });
        } catch (Exception e) {
            logger.error("SanqiSensitivewordEngine checkUserName encode error");
            onComplete.handle(Future.succeededFuture(false));
        }
    }

    /**
     * 检查玩家的取名
     * @param webClient
     * @param serverid 服务器ID
     * @param accountid 账号ID
     * @param userName 用户名称
     * @param userId 用户ID
     * @param ip
     * @param time
     * @return
     */
    public static void checkUserName(WebClient webClient, int serverid, String accountid, String userName,
                                     long userId, String ip, int time, Handler<AsyncResult<Boolean>> onComplete) {

        try {
            // 计算签名
            Map<String, String> param = new  HashMap<>();
            param.put("game_key", PNYZJ_GAME_KEY);
            param.put("sid", String.valueOf(serverid));
            param.put("username", accountid);
            param.put("actor_id", String.valueOf(userId));
            param.put("ip", ip);
            param.put("time", String.valueOf(time));
            String sanqCommonSign = getSanqiCommonSign(param);

            // 构造请求对象
            HttpRequest<Buffer> request = webClient.postAbs(PNYZJ_CHECK_USERNAME_URL).timeout(1000)
                    .addQueryParam("game_key", URLEncoder.encode(PNYZJ_GAME_KEY, "UTF-8"))
                    .addQueryParam("sid", URLEncoder.encode(String.valueOf(serverid), "UTF-8"))//游戏区服ID
                    .addQueryParam("username", URLEncoder.encode(accountid, "UTF-8"))//玩家账号accountid
                    .addQueryParam("actor", URLEncoder.encode(userName, "UTF-8"))//角色名称
                    .addQueryParam("actor_id", URLEncoder.encode(String.valueOf(userId), "UTF-8"))//角色ID
                    .addQueryParam("ip", URLEncoder.encode(ip, "UTF-8"))//玩家ip
                    .addQueryParam("time", URLEncoder.encode(String.valueOf(time), "UTF-8"))//当前Unix时间戳
                    .addQueryParam("sign", URLEncoder.encode(sanqCommonSign, "UTF-8"));//接口签名参数

            request.send(res-> {
                if (res.succeeded()) {
                    String result = res.result().bodyAsString();
                    if (SUCCESS.equals(result)) {
                        onComplete.handle(Future.succeededFuture(true));
                    } else {
                        logger.error("SanqiSensitivewordEngine checkUserName result = {} userName = {} accountid = {} userId = {}", result, userName, accountid, userId);
                        onComplete.handle(Future.succeededFuture(false));
                    }
                } else {

                    if (res.cause().getMessage().contains("timeout")) {
                        onComplete.handle(Future.succeededFuture(true));
                        logger.info("SanqiSensitivewordEngine checkUserName error userName = {} accountid = {} userId = {} cause = {}", userName, accountid, userId, res.cause().getMessage());
                    } else {
                        logger.error("SanqiSensitivewordEngine checkUserName error userName = {} accountid = {} userId = {} cause = {}", userName, accountid, userId, res.cause().getMessage());
                        onComplete.handle(Future.succeededFuture(false));
                    }
                }
            });
        } catch (Exception e) {
            logger.error("SanqiSensitivewordEngine checkUserName encode error");
            onComplete.handle(Future.succeededFuture(false));
        }
    }

    /**
     * 上报工会起名和公告
     * @param webClient 客户端
     * @param serverid 服务器ID
     * @param familyid 同盟ID
     * @param time 时间
     * @param type 1工会名 2工会公告
     * @param content 内容
     * @return
     */
    public static void postFamilyName(WebClient webClient, int serverid, long familyid, int time, int type, String content, Handler<AsyncResult<Boolean>> onComplete) {

        try {
            // 计算签名
            Map<String, String> param = new  HashMap<>();
            param.put("game_key", PNYZJ_GAME_KEY);
            param.put("sid", String.valueOf(serverid));
            param.put("time", String.valueOf(time));
            param.put("type", String.valueOf(type));
            String sanqCommonSign = getSanqiCommonSign(param);

            // 构造请求对象
            HttpRequest<Buffer> request = webClient.postAbs(PNYZJ_POST_FAMILY_NAME_URL).timeout(3000)
                    .addQueryParam("game_key", URLEncoder.encode(PNYZJ_GAME_KEY, "UTF-8"))
                    .addQueryParam("sid", URLEncoder.encode(String.valueOf(serverid), "UTF-8"))//游戏区服ID
                    .addQueryParam("guildid", URLEncoder.encode(String.valueOf(familyid), "UTF-8"))//玩家账号accountid
                    .addQueryParam("time", URLEncoder.encode(String.valueOf(time), "UTF-8"))//当前Unix时间戳
                    .addQueryParam("sign", URLEncoder.encode(sanqCommonSign, "UTF-8"))//接口签名参数
                    .addQueryParam("type", URLEncoder.encode( String.valueOf(type), "UTF-8"))//类型：1：公会名；2：公会公告
                    .addQueryParam("content", URLEncoder.encode( String.valueOf(content), "UTF-8"));//内容

            request.send(res-> {
                if (res.succeeded()) {
                    String result = res.result().bodyAsString();
                    if (SUCCESS.equals(result)) {
                        onComplete.handle(Future.succeededFuture(true));
                    } else {
                        logger.info("SanqiSensitivewordEngine postFamilyName result = {} familyid = {} type = {} content = {}", result, familyid, type, content);
                        onComplete.handle(Future.succeededFuture(false));
                    }
                } else {
                    logger.info("SanqiSensitivewordEngine postFamilyName error familyid = {} type = {} content = {} cause = {}", familyid, type, content, res.cause().getMessage());
                    onComplete.handle(Future.succeededFuture(false));
                }
            });
        } catch (Exception e) {
            logger.info("SanqiSensitivewordEngine postFamilyName encode error");
            onComplete.handle(Future.succeededFuture(false));

        }
    }

    /**
     * 检查工会起名和公告
     * @param webClient 客户端
     * @param serverid 服务器ID
     * @param familyid 同盟ID
     * @param time 时间
     * @param type 1工会名 2工会公告
     * @param content 内容
     * @return
     */
    public static void checkFamilyName(WebClient webClient, int serverid, long familyid, int time, int type, String content, Handler<AsyncResult<Boolean>> onComplete) {

        try {
            // 计算签名
            Map<String, String> param = new  HashMap<>();
            param.put("game_key", PNYZJ_GAME_KEY);
            param.put("sid", String.valueOf(serverid));
            param.put("time", String.valueOf(time));
            param.put("type", String.valueOf(type));
            String sanqCommonSign = getSanqiCommonSign(param);

            // 构造请求对象
            HttpRequest<Buffer> request = webClient.postAbs(PNYZJ_CHECK_FAMILY_NAME_URL).timeout(1000)
                    .addQueryParam("game_key", URLEncoder.encode(PNYZJ_GAME_KEY, "UTF-8"))
                    .addQueryParam("sid", URLEncoder.encode(String.valueOf(serverid), "UTF-8"))//游戏区服ID
                    .addQueryParam("guildid", URLEncoder.encode(String.valueOf(familyid), "UTF-8"))//玩家账号accountid
                    .addQueryParam("time", URLEncoder.encode(String.valueOf(time), "UTF-8"))//当前Unix时间戳
                    .addQueryParam("sign", URLEncoder.encode(sanqCommonSign, "UTF-8"))//接口签名参数
                    .addQueryParam("type", URLEncoder.encode( String.valueOf(type), "UTF-8"))//类型：1：公会名；2：公会公告
                    .addQueryParam("content", URLEncoder.encode( String.valueOf(content), "UTF-8"));//内容

            request.send(res-> {
                if (res.succeeded()) {
                    String result = res.result().bodyAsString();
                    if (SUCCESS.equals(result)) {
                        onComplete.handle(Future.succeededFuture(true));
                    } else {
                        logger.info("SanqiSensitivewordEngine checkFamilyName result = {} familyid = {} type = {} content = {}", result, familyid, type, content);
                        onComplete.handle(Future.succeededFuture(false));
                    }
                } else {
                    // 超时了 也直接返回成功
                    if (res.cause().getMessage().contains("timeout")) {
                        onComplete.handle(Future.succeededFuture(true));
                    } else {
                        logger.info("SanqiSensitivewordEngine checkFamilyName error familyid = {} type = {} content = {} cause = {}", familyid, type, content, res.cause().getMessage());
                        onComplete.handle(Future.succeededFuture(false));
                    }

                }
            });
        } catch (Exception e) {
            logger.info("SanqiSensitivewordEngine checkFamilyName encode error");
            onComplete.handle(Future.succeededFuture(false));

        }
    }

    private static String getSanqiChatSign(String gamekey, int serverid, String accountid,
                                           String toAccountid, String channel,
                                           String ip, int time) {
        String text = gamekey + serverid + accountid + toAccountid + channel + ip + time + PNYZJ_GAME_KEY_SEC;

        return Tool.md5encrypt32(text);
    }

    public static String getSanqiCommonSign(Map<String, String> map) {

        // 字典序升序进行
        ArrayList<String> keyList = new ArrayList<>(map.keySet());
        Collections.sort(keyList);
        StringBuilder text = new StringBuilder();
        for (String key : keyList) {
            String value = map.get(key);
            text.append(key).append("=").append(value);
        }
        text.append(PNYZJ_GAME_KEY_SEC);

        return Tool.md5encrypt32(text.toString());
    }

    /**
     * 获取敏感词
     * @param webClient 客户端
     * @return
     */
    public static Future<JsonArray> getWord(WebClient webClient) {

        Promise<JsonArray> fut = Promise.promise();
        try {

            // 计算签名
            long curTime = TimeUtils.getCurTime();
            Map<String, String> param = new  HashMap<>();
            param.put("game_key", PNYZJ_GAME_KEY);
            param.put("time", String.valueOf(curTime));
            String sanqCommonSign = getSanqiCommonSign(param);

            // 构造请求对象
            HttpRequest<Buffer> request = webClient.postAbs(PNYZJ_GET_WORD_URL).timeout(3000)
                    .addQueryParam("game_key", URLEncoder.encode(PNYZJ_GAME_KEY, "UTF-8"))
                    .addQueryParam("time", URLEncoder.encode(String.valueOf(curTime), "UTF-8"))//当前Unix时间戳
                    .addQueryParam("sign", URLEncoder.encode(sanqCommonSign, "UTF-8"));//接口签名参数
            logger.info("SanqiSensitivewordEngine getWord game_key = {} time = {} sign = {}", PNYZJ_GAME_KEY, curTime, sanqCommonSign);
            request.send(res-> {
                if (res.succeeded()) {
                    String result = res.result().bodyAsString();
//                    logger.info("SanqiSensitivewordEngine getWord" + result);
                    if (result != null) {
                        // 返回值为, 测试||1625053759\n测试||1625053759
                        String[] split = result.split("\n");
                        logger.info("SanqiSensitivewordEngine getWord" + split.length);
                        JsonArray jsonArray = new JsonArray();
                        for (String splitStr : split) {
                            String[] obj = splitStr.split("\\|\\|");
                            if (obj.length > 1) {
                                jsonArray.add(obj[0]);
                            }
                        }
                        fut.complete(jsonArray);
                    } else {
                        logger.info("SanqiSensitivewordEngine getWord result = null");
                        fut.complete(new JsonArray());
                    }
                } else {
                    logger.info("SanqiSensitivewordEngine getWord failure ");
                    fut.complete(new JsonArray());
                }
            });
        } catch (Exception e) {
            fut.complete(new JsonArray());
            logger.info("SanqiSensitivewordEngine getWord encode error");
        }
        return fut.future();
    }
}
